﻿using System;
using System.Linq;
using System.Web;
using System.Web.UI;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

using System.Text;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Configuration;
using System.Drawing;

using CorreoSocialWeb.Views;
using Microsoft.AspNet.Identity.EntityFramework;
using CorreoSocialWeb.Models;

namespace CorreoSocialWeb
{
    public partial class Registrate : Page
    {
        void ddlProvincia_cargar()
        {
            try
            {
                this.LabelError.Text = String.Empty;

                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
                myConnection.Open();
                SqlCommand myCommand = new SqlCommand("SELECT UPPER(nombre) AS nombre, id  FROM provincias", myConnection);
                SqlDataReader myReader = myCommand.ExecuteReader();
                ddlProvincia.DataSource = myReader;
                ddlProvincia.DataBind();

                ddlProvincia.Items.Insert(0, new ListItem("(seleccionar)"));
            }
            catch
            {
                this.LabelError.Text = "Ocurrió un error al cargar las provincias. Intentelo más tarde.";
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
                return;

            ddlProvincia_cargar();
        }

        public String generarNombreDeArchivo()
        {
            Int32 size = 128;
            StringBuilder builder = new StringBuilder();
            Random random = new Random(System.DateTime.Now.Millisecond);
            
            char ch;

            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }

            return builder.ToString();
        }

        private String subirArchivo(FileUpload archivo)
        {
            String path = Server.MapPath(@"~/Files/");
            String fileExtension = System.IO.Path.GetExtension(archivo.FileName).ToLower();
            String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
            String nombreArchivo = generarNombreDeArchivo() + fileExtension;

            archivo.PostedFile.SaveAs(path + nombreArchivo);
            return nombreArchivo;
        }

        private void LimpiarLabels()
        {
            LabelError.Text = 

            lblErrorNombreUsuario.Text = 
            lblErrorCorreo.Text = 
            lblErrorPassword.Text = 
            lblErrorConfirmar.Text =

            lblErrorNombre.Text = 
            lblErrorApellido.Text =
            lblErrorFechaNac.Text = 
            lblErrorDni.Text = 

            lblErrorDomicilio.Text = 
            lblErrorProv.Text = 
            lblErrorLoc.Text = 

            lblErrorCelular.Text = 
            lblErrorFijo.Text = 

            lblErrorDNI1.Text = 
            lblErrorDNI1.Text = 
            lblErrorServ1.Text = 
            lblErrorServ2.Text = string.Empty;
        }

        private bool validar(out ErroresHelper errores)
        {
            errores = new ErroresHelper();

            Label errorLabel;

            LimpiarLabels();

            Page currentPage = HttpContext.Current.Handler as Page;

            // usuario
            errorLabel = lblErrorNombreUsuario;
            if (NombreDeUsuario.Text.Equals(String.Empty))
                errores.Add("Ingresá un Nombre de Usuario.", errorLabel);
            else if (Usuario.ExisteNombreDeUsuario(NombreDeUsuario.Text.Trim().ToLower()))
                errores.Add("El Nombre de usuario que elegiste está en uso. Por favor, elegí uno diferente.", errorLabel);
            
            // email
            errorLabel = lblErrorCorreo;
            if (!new RegexUtilities().IsValidEmail(Email.Text.Trim()))
                errores.Add("Ingresá una Email válido.", errorLabel);
            else if (Usuario.ExisteMail(Email.Text.Trim().ToLower()))
                errores.Add("Ya existe un usuario registrado con el Email que ingresaste.", errorLabel);

            // contraseña
            errorLabel = lblErrorPassword;
            if (Password.Text.Equals(String.Empty))
                errores.Add("Ingresá tu Contraseña.", errorLabel);
            else if (Password.Text.Contains(" "))
                errores.Add("La contraseña no puede contener espacios.", errorLabel);
            else
            {
                Regex regex = new Regex(@"^([\w]{6,20})$");
                Match match = regex.Match(Password.Text);

                if (!match.Success)
                    errores.Add("La contraseña debe tener mínimo 6 y máximo 20 letras/números.", errorLabel);
            }

            // confirm contraseña
            errorLabel = lblErrorConfirmar;
            if (ConfirmPassword.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá la confirmación de tu Contraseña.", errorLabel);
            else if (!ConfirmPassword.Text.Equals(Password.Text))
                errores.Add("La contraseña y su confirmación no coinciden.", errorLabel);

            // nombre
            errorLabel = lblErrorNombre;
            if (txtNombre.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá tu Nombre.", errorLabel);
            else if (txtNombre.Text.Trim().Length < 4)
                errores.Add("Tu Nombre debe ser de al menos 4 letras.", errorLabel);

            // apellido
            errorLabel = lblErrorApellido;
            if (txtApellido.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá tu Apellido.", errorLabel);
            else if (txtNombre.Text.Trim().Length < 3)
                errores.Add("Tu Apellido debe ser de al menos 4 letras.", errorLabel);

            // fecha nac
            errorLabel = lblErrorFechaNac;
            if (txtFechaNac.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá tu Fecha de Nacimiento.", errorLabel);
            else
            {
                if (Convert.ToDateTime(txtFechaNac.Text, System.Globalization.CultureInfo.GetCultureInfo("es-AR"))
                    .AddYears(17).Year > DateTime.Now.Year)
                    errores.Add("Fecha de Nacimiento inválida: Debe ser mayor de 18 años.", errorLabel);
            }

            errorLabel = lblErrorDni;
            if (txtDNI.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá tu Número de Documento.", errorLabel);
            else
            {
                Regex regex = new Regex(@"[0-9]{8}");
                Match match = regex.Match(txtDNI.Text.Trim().Replace(".",string.Empty));

                if (!match.Success)
                    errores.Add("Ingresá un Número de Documento válido.", errorLabel);
            }

            // domicilio
            errorLabel = lblErrorDomicilio;
            if (txtDomicilio.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá un Domicilio valido.", errorLabel);
            
            // provincia
            errorLabel = lblErrorProv;
            if (ddlProvincia.SelectedIndex == 0)
                errores.Add("Seleccioná una Provincia.", errorLabel);

            // localidad
            errorLabel = lblErrorLoc;
            if (ddlLocalidad.SelectedIndex == 0)
                errores.Add("Seleccioná un Partido/Departamento.", errorLabel);

            // celular 
            errorLabel = lblErrorCelular;
            if (txtCelular1.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá tu Número de Celular.", errorLabel);
            else
            {
                if (!ValidadorDeTelefono.Validar(txtCelular1.Text))
                    errores.Add("Ingresá un Número de Celular válido.", errorLabel);
            }

            // telefono fijo 
            errorLabel = lblErrorFijo;
            if (txtFijo.Text.Trim().Equals(String.Empty))
                errores.Add("Ingresá tu Teléfono Fijo.", errorLabel);
            else
            {
                if (!ValidadorDeTelefono.Validar(txtFijo.Text))
                    errores.Add("Ingresá un Teléfono Fijo válido.", errorLabel);
            }

            // dni 1
            errorLabel = lblErrorDNI1;
            if (fuDNI1.FileName.Trim().Equals(String.Empty))
                errores.Add("Seleccioná imagen del DNI frente/primera hoja.", errorLabel);
            else
            {
                Boolean extencionOK = false;
                String fileExtension = System.IO.Path.GetExtension(fuDNI1.FileName).ToLower();
                String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
                for (int i = 0; i < allowedExtensions.Length; i++)
                    if (fileExtension == allowedExtensions[i])
                    {
                        extencionOK = true;
                        break;
                    }

                if (!extencionOK)
                {
                    errores.Add("Extensión de archivo [" + System.IO.Path.GetFileName(fuDNI1.FileName) + "] incorrecta. Debe ser .gif .png . jpg .jpeg", errorLabel);
                    currentPage.Validators.Add(new ValidationError(lblErrorDNI1.Text));
                }
                else
                {
                    Bitmap LaImagen = new System.Drawing.Bitmap(fuDNI1.PostedFile.InputStream);
                    if (LaImagen.Width <= 640 && LaImagen.Height <= 480)
                        errores.Add("El tamaño de la imagen [" + System.IO.Path.GetFileName(fuDNI1.FileName) + "] debe ser mayor a 640 x 480 pixel.", errorLabel);
                }
            }

            // dni 2
            errorLabel = lblErrorDNI1;
            if (fuDNI2.FileName.Trim().Equals(String.Empty))
                errores.Add("Seleccioná imagen del DNI dorso/segunda hoja.", errorLabel);
            else
            {
                Boolean extencionOK = false;
                String fileExtension = System.IO.Path.GetExtension(fuDNI2.FileName).ToLower();
                String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
                for (int i = 0; i < allowedExtensions.Length; i++)
                    if (fileExtension == allowedExtensions[i])
                    {
                        extencionOK = true;
                        break;
                    }

                if (!extencionOK)
                    errores.Add("Extensión de archivo [" + System.IO.Path.GetFileName(fuDNI2.FileName) + "] incorrecta. Debe ser .gif .png . jpg .jpeg", errorLabel);
                else
                {
                    Bitmap LaImagen = new System.Drawing.Bitmap(fuDNI2.PostedFile.InputStream);
                    if (LaImagen.Width <= 640 && LaImagen.Height <= 480)
                        errores.Add("El tamaño de la imagen [" + System.IO.Path.GetFileName(fuDNI2.FileName) + "] debe ser mayor a 640 x 480 pixel.", errorLabel);
                }
            }

            // serivicio 1
            errorLabel = lblErrorServ1;
            if (fuServicio1.FileName.Equals(String.Empty))
                errores.Add("Seleccioná imagen de la factura de servicio frente.", errorLabel);
            else
            {
                Boolean extencionOK = false;
                String fileExtension = System.IO.Path.GetExtension(fuServicio1.FileName).ToLower();
                String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
                for (int i = 0; i < allowedExtensions.Length; i++)
                    if (fileExtension == allowedExtensions[i])
                    {
                        extencionOK = true;
                        break;
                    }

                if (!extencionOK)
                    errores.Add("Extensión de archivo [" + System.IO.Path.GetFileName(fuServicio1.FileName) + "] incorrecta. Debe ser .gif .png . jpg .jpeg", errorLabel);
                else
                {
                    Bitmap LaImagen = new System.Drawing.Bitmap(fuServicio1.PostedFile.InputStream);
                    if (LaImagen.Width <= 640 && LaImagen.Height <= 480)
                        errores.Add("El tamaño de la imagen [" + System.IO.Path.GetFileName(fuServicio1.FileName) + "] debe ser mayor a 640 x 480 pixel.", errorLabel);
                }
            }

            // servicio 2
            errorLabel = lblErrorServ2;
            if (fuServicio2.FileName.Equals(String.Empty))
                errores.Add("Seleccioná imagen de la factura de servicio dorso.", errorLabel);
            else
            {
                Boolean extencionOK = false;
                String fileExtension = System.IO.Path.GetExtension(fuServicio2.FileName).ToLower();
                String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
                for (int i = 0; i < allowedExtensions.Length; i++)
                    if (fileExtension == allowedExtensions[i])
                    {
                        extencionOK = true;
                        break;
                    }

                if (!extencionOK)
                    errores.Add("Extensión de archivo [" + System.IO.Path.GetFileName(fuServicio2.FileName) + "] incorrecta. Debe ser .gif .png . jpg .jpeg", errorLabel);
                else
                {
                    Bitmap LaImagen = new System.Drawing.Bitmap(fuServicio2.PostedFile.InputStream);

                    if (LaImagen.Width <= 640 && LaImagen.Height <= 480)
                        errores.Add("El tamaño de la imagen [" + System.IO.Path.GetFileName(fuServicio2.FileName) + "] debe ser mayor a 640 x 480 pixel.", errorLabel);
                }
            }

            return !errores.HayErrores;
        }

        private void EnviarMailVerificacion(string nombreDeUsuario)
        {
            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var user = manager.FindByName(nombreDeUsuario);
            
            string code = manager.GenerateEmailConfirmationToken(user.Id);

            var paginaConRandom = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id);

            var url = Views.SiteUrlHelper.Get(this, string.Format(paginaConRandom));

            var db = new CorreoSocialDbContext();

            Usuario usuario = new CorreoSocialDbContext().Usuarios.FirstOrDefault(x => x.Id.Equals(user.UsuarioId));

            usuario.MandarMailConfirmacion(url);

            usuario.EstadoEnu = EstadoUsuarioEnu.MailSinConfirmar;

            db.SaveChanges();
        }

        protected void CreateUser_Click(object sender, EventArgs e)
        {
            ErroresHelper errores = new ErroresHelper();

            this.LabelError.Text = string.Empty;

            try
            {
                if (!validar(out errores))
                {
                    this.LabelError.Text = "Hubo errores de validación. Revisá los valores ingresados y volvé a intentarlo.";
                    this.NavegadorUserControl.Focus();
                    return;
                }
                
                String DNI1 = subirArchivo(fuDNI1);
                String DNI2 = subirArchivo(fuDNI2);
                String Serv1 = subirArchivo(fuServicio1);
                String Serv2 = subirArchivo(fuServicio2);

                int domicilioId;

                var db = new CorreoSocialDbContext();
                Domicilio domicilio = new Domicilio();
                domicilio.Direccion = txtDomicilio.Text;
                domicilio.PartidoID = Convert.ToInt32(ddlLocalidad.SelectedValue);
                db.Domicilios.Add(domicilio);
                db.SaveChanges();

                domicilioId = domicilio.Id;

                var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();

                var user = new ApplicationUser();

                user.UserName = NombreDeUsuario.Text.Trim();
                user.Email = Email.Text.Trim();
                user.Nombre = txtNombre.Text.Trim();
                user.Apellido = txtApellido.Text.Trim();
                user.DomicilioId = domicilioId;
                user.DNI = Convert.ToInt32(txtDNI.Text);
                user.FechaNacimiento = Convert.ToDateTime(txtFechaNac.Text, System.Globalization.CultureInfo.GetCultureInfo("es-AR"));
                user.NroTelefonoCelular = txtCelular1.Text.Trim();
                user.NroTelefonoFijo = txtFijo.Text.Trim();

                user.FotoDNI1 = DNI1;
                user.FotoDNI2 = DNI2;
                user.FotoServicio1 = Serv1;
                user.FotoServicio2 = Serv2;

                user.Reputacion = 0;

                // agrego el user al grupo de usuarios
                IdentityUserRole i = new IdentityUserRole();
                i.RoleId = "1"; // grupo de usuarios (no admins)
                i.UserId = user.Id;

                user.Roles.Add(i);

                IdentityResult result = manager.Create(user, Password.Text);

                if (result.Succeeded)
                {
                    EnviarMailVerificacion(user.UserName);

                    Response.Redirect("UsuarioCreado.aspx", false);
                }
                else
                    this.LabelError.Text = "Ocurrio un error al crear el usuario. Intentelo mas tarde.";
            }
            catch 
            {
                this.LabelError.Text = "Ocurrió un error al registrarte. Por favor, intentá nuevamente más tarde.";
            }
        }

        protected void ddlProvincia_SelectedIndexChanged1(object sender, EventArgs e)
        {
            try
            {
                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
                myConnection.Open();
                SqlDataReader myReader = null;
                string strCadSQL = "SELECT UPPER(par.nombre) AS nombre, par.id  FROM partidos par, provincias prov where par.provinciaid = prov.id AND prov.id = " + ddlProvincia.SelectedValue;
                SqlCommand myCommand = new SqlCommand(strCadSQL, myConnection);
                myReader = myCommand.ExecuteReader();
                ddlLocalidad.DataSource = myReader;
                ddlLocalidad.DataBind();
                ddlLocalidad.Items.Insert(0, new ListItem("(seleccionar)"));

                this.LabelError.Text = string.Empty;
            }
            catch
            {
                this.LabelError.Text = "Ocurrio un error al cargar las provincias. ";
            }
        }
    }
}